home *** CD-ROM | disk | FTP | other *** search
- # include <errors.h>
- # include <ingres.h>
- # include <aux.h>
- # include <opsys.h>
- # include <access.h>
- # include <tree.h>
- # include <symbol.h>
- # include "globs.h"
- # include <sccs.h>
-
- SCCSID(@(#)call_ovqp.c 8.6 12/18/85)
-
-
- /*
- ** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
- **
- ** This file contains the routines associated with sending queries
- ** and receiving results from OVQP. The interface to these routines is
- ** still messy. Call_ovqp is given the query, mode, and result relation
- ** as parameters and gets the source relation, and two flags
- ** (De.de_newq, De.de_newr) as globals. The routines include:
- **
- ** Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
- **
- ** Readresult -- Reads the result from a one-var query.
- **
- ** Endovqp -- Informs ovqp that the query is over. Helps to synchronize
- ** the batch file (if any).
- **
- ** Trace Flags:
- ** 61
- */
- /*
- ** Call_ovqp -- send query down pipe to ovqp and flush pipe.
- ** Inputs are:
- ** mode retrieve, append, etc.
- ** resultnum result relation id
- ** tree the query
- ** De.de_sourcevar (global) if >= 0 then source var
- ** De.de_newq send NEWQ symbol
- ** De.de_newr send NEWR symbol
- */
-
- call_ovqp(tree, mode, resultnum)
- register QTREE *tree;
- int mode;
- int resultnum;
- {
- register int i;
- char *rangename();
- extern int derror();
- extern bool Batchupd;
- extern DESC Inddes;
- int ovqpbuf[1+LBUFSIZE/sizeof(int)];
- DESC *readopen();
- extern DESC *specopen();
- extern char *rnum_convert();
-
-
- # ifdef xDTR1
- if (tTf(61, -1))
- {
- if (tTf(61, 0))
- printf("CALL_OVQP-\n");
- if (tTf(61, 1))
- {
- if (De.de_newq)
- {
- printf("new query to ovqp\n");
- treepr(tree);
- }
- else
- printf("query same as previous\n");
- }
- if (tTf(61, 2))
- {
- printf("De.de_sourcevar=%d\t", De.de_sourcevar);
- if (De.de_sourcevar >= 0)
- printf("relid=%s\t", rangename(De.de_sourcevar));
- if (resultnum >= 0)
- printf("De.ov_resultname=%s", rnum_convert(resultnum));
- if (tree->sym.value.sym_root.rootuser)
- printf(", userqry");
- printf("\n");
- }
- }
- # endif
-
-
-
- /* assign mode of this query */
- De.de_qmode = mode;
-
- if (De.de_newr)
- {
- De.de_newr = FALSE;
- }
-
- if (resultnum >= 0)
- {
- De.ov_result = specopen(resultnum);
- }
- else
- De.ov_result = NULL;
-
- if (De.de_sourcevar >= 0)
- De.ov_source = readopen(De.de_sourcevar);
- else
- De.ov_source = NULL;
-
- /* assume this will be direct update */
- De.ov_userqry = De.de_buflag = FALSE;
-
- if (tree->sym.value.sym_root.rootuser)
- {
- De.ov_userqry = TRUE;
- /* handle batch file */
- if (De.ov_result && De.de_qmode != mdRETR)
- {
- if (Batchupd || De.ov_result->reldum.relindxd > 0)
- {
- if (De.ov_bopen == 0)
- {
- if (De.ov_result->reldum.relindxd > 0)
- opencatalog("indexes", OR_READ);
- if (i = openbatch(De.ov_result, &Inddes, De.de_qmode))
- syserr("call_ovqp:opn batch %d", i);
- De.ov_bopen = TRUE;
- }
- De.de_buflag = TRUE;
- }
- }
- }
-
- /* now write the query list itself */
- if (De.de_newq)
- {
- De.ov_ovqpbuf = (char *)ovqpbuf;
- initbuf(De.ov_ovqpbuf, LBUFSIZE, LISTFULL, derror);
- De.de_qvptr = 0;
- De.ov_alist = De.ov_bylist = De.ov_qlist = De.ov_tlist = NULL;
- De.ov_targvc = tree->sym.value.sym_root.lvarc;
- De.ov_qualvc = bitcnt(tree->sym.value.sym_root.rvarm);
- De.ov_agcount = 0;
-
- if (tree->sym.type == AGHEAD)
- {
- De.ov_alist = &De.de_qvect[0];
- if (tree->left->sym.type == BYHEAD)
- {
- mklist(tree->left->right);
- ovqpnod(tree->left); /* BYHEAD node */
- De.ov_bylist = &De.de_qvect[De.de_qvptr];
- mklist(tree->left->left);
- }
- else
- mklist(tree->left);
- }
- else
- {
- if (tree->left->sym.type != TREE)
- {
- De.ov_tlist = &De.de_qvect[0];
- mklist(tree->left);
- }
- }
-
- /* now for the qualification */
- ovqpnod(tree); /* ROOT node */
-
- if (tree->right->sym.type != QLEND)
- {
- De.ov_qlist = &De.de_qvect[De.de_qvptr];
- mklist(tree->right);
- }
- ovqpnod(De.de_qle); /* QLEND node */
- }
-
- /* Now call ovqp */
- if (strategy())
- {
- i = scan(); /* scan the relation */
- }
- else
- i = EMPTY;
-
- /* return result of query */
- return (i == NONEMPTY); /* TRUE if tuple satisfied */
- }
- /*
- ** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
- ** whether to wait for an acknowledgement from ovqp. The overall
- ** mode of the query is sent followed by an EXIT command.
- **
- ** Ovqp decides whether to use batch update or not. If ack == ACK
- ** then endovqp will read a RETVAL symbol from ovqp and return
- ** a token which specifies whether to call the update processor or not.
- */
-
- endovqp(ack)
- int ack;
- {
- register int i;
-
- if (ack != RUBACK)
- {
- if (Equel && De.de_qry_mode == mdRETTERM)
- equeleol(EXIT); /* signal end of retrieve to equel process */
- }
-
- i = NOUPDATE;
-
- if (ack == ACK)
- {
- if (De.ov_bopen)
- {
- closebatch();
- De.ov_bopen = FALSE;
- i = UPDATE;
- }
- }
- else
- {
- if (De.ov_bopen)
- {
- rmbatch();
- De.ov_bopen = FALSE;
- }
- }
-
- closecatalog(FALSE);
-
- return (i);
- }
- /*
- ** Add node q to ovqp's list
- */
-
- ovqpnod(q)
- register QTREE *q;
- {
- register SYMBOL *s;
- extern QTREE *ckvar();
- extern char *need();
- register int i;
-
- s = &q->sym;
-
- /* VAR nodes must be specially processed */
- if (s->type == VAR)
- {
- /* locate currently active VAR */
- q = ckvar(q);
-
- /* Allocate an ovqp var node for the VAR */
- s = (SYMBOL *) need(De.ov_ovqpbuf, SYM_HDR_SIZ + sizeof s->value.sym_var);
- s->len = sizeof s->value.sym_var;
- s->value.sym_var.attno = q->sym.value.sym_var.attno;
- s->value.sym_var.varfrmt = q->sym.value.sym_var.varfrmt;
- s->value.sym_var.varfrml = q->sym.value.sym_var.varfrml;
- s->value.sym_var.varstr = q->sym.value.sym_var.varstr;
-
- /* If VAR has been substituted for, get value */
- if (q->sym.value.sym_var.valptr)
- {
- /* This is a substituted variable */
- if (q->sym.value.sym_var.varno == De.de_sourcevar)
- syserr("ovqpnod:bd sub %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
-
- s->type = S_VAR;
- s->value.sym_var.valptr = q->sym.value.sym_var.valptr;
- }
- else
- {
- /* Var for one variable query */
- if (q->sym.value.sym_var.varno != De.de_sourcevar)
- syserr("ovqpnod:src var %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
- s->type = VAR;
- i = q->sym.value.sym_var.attno;
- if (i != 0)
- s->value.sym_var.valptr = (ANYTYPE *) (De.ov_intup + De.ov_source->reloff[i]);
- else
- s->value.sym_var.valptr = (ANYTYPE *) &De.ov_intid;
- }
- }
- if (s->type == AOP)
- De.ov_agcount++;
-
- /* add symbol to list */
- if (De.de_qvptr > MAXNODES - 1)
- ov_err(NODOVFLOW);
- De.de_qvect[De.de_qvptr++] = s;
- }
- /*
- ** READAGG_RESULT
- */
-
- readagg_result(result)
- QTREE *result[];
- {
- register QTREE **r, *aop;
- register int i;
-
- De.ov_tend = De.ov_outtup;
- r = result;
-
- while (aop = *r++)
- {
- i = aop->sym.len & I1MASK;
-
- if (aop->sym.type == CHAR)
- pad(De.ov_tend, i);
-
- bmove(De.ov_tend, (char *)&aop->sym.value, i);
-
- De.ov_tend += i;
- # ifdef xDTR1
- if (tTf(61, 3))
- nodepr(aop);
- # endif
- }
- }
-
-
- ov_err(code)
- int code;
- {
- derror(code);
- }
-
-
- DESC *
- openindex(name)
- char *name;
- {
- register DESC *d;
- register int varno;
- DESC *readopen();
-
- varno = SECINDVAR;
- De.de_rangev[varno].relnum = rnum_findadd(name);
- d = readopen(varno);
- return (d);
- }
- /*
- ** Use "closer()" for closing relations. See
- ** desc_close in openrs.c for details.
- */
- extern int closer();
- int (*Des_closefunc)() = closer;
-
- init_decomp()
- {
- static struct accbuf xtrabufs[12];
-
- set_so_buf();
- acc_addbuf(xtrabufs, 12);
- }
-
-
- startdecomp()
- {
- /* called at the start of each user query */
- initrange();
- rnum_init();
- startovqp();
- }
-